﻿using CommunityToolkit.Mvvm.ComponentModel;
using DX.Views;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;

namespace DX.ViewModels
{

    public abstract partial class ViewModel : ObservableObject, IViewModel, IAttach, IDetach, IHaveDisplayName, IGuardClose
    {

        public virtual byte[] CustomIcon { get; }
        public ViewModelContext Context { get; protected set; }




        internal bool actuallyClosing = false;
        [ObservableProperty]
        private string title = "";
        [ObservableProperty]
        private IView view;
        [CommunityToolkit.Mvvm.Input.RelayCommand]
        public async Task TryClose(bool? dialogResult)
        {

            if (dialogResult.HasValue && dialogResult.Value)
            {
                actuallyClosing = true;

            }
            if (!actuallyClosing)
            {
                var flag = await OnCanClose();
                if (flag)
                {
                    actuallyClosing = true;
                }
            }
            if (actuallyClosing)
            {
                await Context.ServiceProvider.GetRequiredService<ICloseStrategy>().GetCloseAction(View, true);
            }
        }

        protected virtual void OnAttach(IView view, IViewModel viewModel)
        {
            if (!this.Equals(viewModel)) throw new ViewNotAttachException("ViewModel can not binding in this view");
            this.View = view;

        }

        protected virtual void OnDetach(IView view, IViewModel viewModel)
        {
            if (!this.Equals(viewModel)) throw new ViewNotDetachException("ViewModel no binding in this view");
            this.View = null;
        }
        void IAttach.Attach(IView view, IViewModel viewModel)
        {
            OnAttach(view, viewModel);
        }

        void IDetach.Detach(IView view, IViewModel viewModel)
        {
            OnDetach(view, viewModel);
        }
        protected virtual Task<bool> OnCanClose()
        {
            return Task.FromResult(true);
        }
        public Task<bool> CanClose()
        {
            return OnCanClose();
        }

        bool IClose.GetActuallyClosing()
        {
            return actuallyClosing;
        }
    }
}
